var relatext = ["当前企业", "企业股东", "法人代表", "个人股东或高管", "企业对外投资", "法人对外投资或任职", "股东高管对外投资或任职", "对外负责个体户"];
var relacolors = ['#c23531', '#DA1B73', '#911BDA', '#1984C7', '#C79F19', '#C719B9'];
//---------------------------------------------------------------d3树图-------------------------------------------------------------------//
var margin = {top: 20, right: 20, bottom: 20, left: 20},
    width = $("#d3treechart").width(),
    height = $("#d3treechart").height(),
    rxo = width / 4,
    ryo = 30;
var i = 0,
    duration2 = 750,
    root2;
var tree2 = d3.layout.tree()
    .size([height, width]);
var diagonal2 = d3.svg.diagonal()
    .projection(function (d) {
        return [d.x, d.y];
    });
var svg2 = d3.select("#d3treechart")
    .append("svg")
    .call(d3.behavior.zoom().on("zoom", redraw2))
    .on('dblclick.zoom', null)
    .attr("id", "svgtreebox")
    .attr("width", width + margin.right + margin.left)
    .attr("height", height + margin.top + margin.bottom)
    .attr("pointer-events", "all")
    .append("g")
    .attr("id", "treebox")
    .attr("transform", "translate(" + rxo + "," + ryo + ")")
    .append("g");
var d3tree2 = function (flare) {
    root2 = flare;
    root2.x0 = height / 2;
    root2.y0 = 0;
    function collapse(d) {
        if (d.children) {
            d._children = d.children;
            d._children.forEach(collapse);
            d.children = null;
        }
    }

    //root.children.forEach(collapse);
    update2(root2);
};
d3.select(self.frameElement).style("height", "800px");
function update2(source) {
    // Compute the new tree layout.
    var nodes = tree2.nodes(root2).reverse(),
        links = tree2.links(nodes);
    // Normalize for fixed-depth.
    nodes.forEach(function (d) {
        d.y = d.depth * 180;
    });
    // Update the nodes…
    var node = svg2.selectAll("g.node")
        .data(nodes, function (d) {
            return d.id || (d.id = ++i);
        });
    // Enter any new nodes at the parent's previous position.
    var nodeEnter = node.enter().append("g")
        .attr("class", "node")
        .attr("transform", function (d) {
            return "translate(" + source.y0 + "," + source.x0 + ")";
        })
        .on('mouseover', function (d) {
            paneldetail(d.eid, "tree");
            //if (activeNode !== null) {
            //    return;
            //}
        })
        .on('mouseout', function (d) {
            hidepaneldetail("tree");
        })
        .on("click", click2);
    nodeEnter.append("circle")
        .attr("r", function (d) {
            if (d.tags == 0) return 12;
            return 9;
        })
        .attr('stroke', function (d) {
            return relacolors[d.tags];
        })
        .attr('stroke-width', function (d) {
            if (d.tags == 0) return 10;
            return 6;
        })
        .attr('stroke-opacity', function (d) {
            return 0.5;
        })
        .attr("fill", function (d) {
            return relacolors[d.tags];
        });
    nodeEnter.append("text")
        .attr("x", function (d) {
            if (d.tags == 0) {
                return 20;
            }
            else {
                return d.children || d._children ? 10 : 10;
            }
        })
        .attr("transform", function (d) {
            if (d.tags == 0 || d.tags == 2) {
                return "rotate(0)";
            }
            else {
                return "rotate(90)";
            }
        })
        .attr("class", "nodetext")
        .attr("dy", ".35em")
        //.attr("text-anchor", function (d) {
        //    return d.children || d._children ? "end" : "start";
        //})
        .text(function (d) {
            return d.name;
        })
        .style("fill-opacity", 1e-6);
    // Transition nodes to their new position.
    var nodeUpdate = node.transition()
        .duration(duration2)
        .attr("transform", function (d) {
            return "translate(" + d.x + "," + d.y + ")";
        });
    nodeUpdate.select("circle")
        .attr("r", function (d) {
            if (d.tags == 0) return 10;
            return 6;
        })
        .style("fill", function (d) {
            //return d._children ? "lightsteelblue" : "#fff";
            return relacolors[d.tags];
        });
    nodeUpdate.select("text")
        .style("fill-opacity", 1);
    // Transition exiting nodes to the parent's new position.
    var nodeExit = node.exit().transition()
        .duration(duration2)
        .attr("transform", function (d) {
            return "translate(" + source.y + "," + source.x + ")";
        })
        .remove();
    nodeExit.select("circle")
        .attr("r", 1e-6);
    nodeExit.select("text")
        .style("fill-opacity", 1e-6);
    // Update the links…
    var link = svg2.selectAll("path.link")
        .data(links, function (d) {
            return d.target.id;
        });
    // Enter any new links at the parent's previous position.
    link.enter().insert("path", "g")
        .attr("class", "link")
        .attr("d", function (d) {
            var o = {x: source.x0, y: source.y0};
            return diagonal2({source: o, target: o});
        });
    // Transition links to their new position.
    link.transition()
        .duration(duration2)
        .attr("d", diagonal2);
    // Transition exiting nodes to the parent's new position.
    link.exit().transition()
        .duration(duration2)
        .attr("d", function (d) {
            var o = {x: source.x, y: source.y};
            return diagonal2({source: o, target: o});
        })
        .remove();
    // Update the link text
    var linktext = svg2.selectAll("g.link")
        .data(links, function (d) {
            return d.target.name;
        });
    linktext.enter()
        .insert("g")
        .attr("class", "link")
        .append("text")
        .attr("dy", ".35em")
        .attr("class", "linktext")
        .attr("text-anchor", "middle")
        .attr("fill", function (d) {
            return relacolors[d.target.tags];
        })
        .text(function (d) {
            return d.target.relation;
        });
    // Transition link text to their new positions
    linktext.transition()
        .duration(duration2)
        .attr("transform", function (d) {
            return "translate(" + d.target.x + "," + (d.target.y - 20) + ")";
        });
    //Transition exiting link text to the parent's new position.
    linktext.exit().transition()
        .remove();
    // Stash the old positions for transition.
    nodes.forEach(function (d) {
        d.x0 = d.x;
        d.y0 = d.y;
    });
}
//---------------------------------------------------------------d3 circle tree-------------------------------------------------------------------//
var i = 0,
    duration = 750,
    root,
    activeNode;
var tree = d3.layout.tree()
    .size([360, width / 2 - 80])
    .separation(function (a, b) {
        return (a.parent == b.parent ? 1 : 2) / a.depth;
    });
var diagonal = d3.svg.diagonal.radial()
    .projection(function (d) {
        return [d.y, d.x / 180 * Math.PI];
    });
var svg = d3.select("#d3circletree")
    .append("svg")
    .call(d3.behavior.zoom().on("zoom", redraw))
    .on('dblclick.zoom', null)
    .attr("id", "svgtreebox")
    .attr("width", width + margin.right + margin.left)
    .attr("height", height + margin.top + margin.bottom)
    .attr("pointer-events", "all")
    .append("g")
    .attr("id", "treebox")
    .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")")
    .append("g");
var d3tree1 = function (flare) {
    root = flare;
    root.x0 = height / 2;
    root.y0 = 0;
    function collapse(d) {
        if (d.children) {
            d._children = d.children;
            d._children.forEach(collapse);
            d.children = null;
        }
    }

    //root.children.forEach(collapse);
    update(root);
};
d3.select(self.frameElement).style("height", "800px");
function update(source) {
// Compute the new tree layout.
    var nodes = tree.nodes(root),
        links = tree.links(nodes);
    // Normalize for fixed-depth.
    nodes.forEach(function (d) {
        d.y = d.depth * 170;
    });
    // Update the nodes…
    var node = svg.selectAll("g.node")
        .data(nodes, function (d) {
            return d.id || (d.id = ++i);
        });
    // Enter any new nodes at the parent's previous position.
    var nodeEnter = node.enter().append("g")
        .attr("class", "node")
        .on('mouseover', function (d) {
            select(d.name);
            paneldetail(d.eid, "circle");
            if (activeNode !== null) {
                return;
            }
            fade(0.2)(d);
        })
        .on('mouseout', function (d) {
            unselect();
            if (activeNode !== null) {
                return;
            }
            fade(1)(d);
            hidepaneldetail("circle");
        })
        .on("click", click);
    nodeEnter.append("circle")
        .attr("r", function (d) {
            if (d.tags == 0) return 10;
            return 7;
        })
        .attr('stroke', function (d) {
            return relacolors[d.tags];
        })
        .attr('stroke-width', function (d) {
            if (d.tags == 0) return 8;
            return 4;
        })
        .attr('stroke-opacity', function (d) {
            return 0.5;
        })
        .attr("fill", function (d) {
            return relacolors[d.tags];
        });
    nodeEnter.append("text")
        .attr("x", function (d) {
            return d.x < 180 ? "10" : "0";
        })
        .attr("dy", ".35em")
        .attr("class", "nodetext")
        .attr("text-anchor", function (d) {
            return d.x < 180 ? "start" : "end";
        })
        .text(function (d) {
            return d.name;
        })
        .style("fill-opacity", 1e-6);
    // Transition nodes to their new position.
    var nodeUpdate = node.transition()
        .duration(duration)
        .attr("transform", function (d) {
            if (d.tags == 0) {
                return "rotate(0)translate(0)";
            } else {
                return "rotate(" + (d.x - 90) + ")translate(" + d.y + ")";
            }
        });

    nodeUpdate.select("circle")
        .attr("r", function (d) {
            if (d.tags == 0) return 8;
            return 4;
        })
        .style("fill", function (d) {
            //return d._children ? "lightsteelblue" : "#fff";
            return relacolors[d.tags];
        });
    nodeUpdate.select("text")
        .style("fill-opacity", 1)
        .attr("transform", function (d) {
            if (d.tags == 0) {
                return "rotate(0)translate(0)"
            } else {
                return d.x < 180 ? "translate(0)" : "rotate(180)translate(-" + (d.name.length) + ")";
            }

        });

    ///////////// appropriate transform/////////////
    var nodeExit = node.exit().transition()
        .duration(duration)
        //.attr("transform", function(d) { return "diagonal(" + source.y + "," + source.x + ")"; })
        .remove();
    nodeExit.select("circle")
        .attr("r", 1e-6);
    nodeExit.select("text")
        .style("fill-opacity", 1e-6);
    // Update the links…
    var link = svg.selectAll("path.link")
        .data(links, function (d) {
            return d.target.id;
        });
    // Enter any new links at the parent's previous position.
    link.enter().insert("path", "g")
        .attr("class", "link")
        .attr("d", function (d) {
            var o = {x: source.x0, y: source.y0};
            return diagonal({source: o, target: o});
        });
    // Transition links to their new position.
    link.transition()
        .duration(duration)
        .attr("d", diagonal);
    // Transition exiting nodes to the parent's new position.
    link.exit().transition()
        .duration(duration)
        .attr("d", function (d) {
            var o = {x: source.x, y: source.y};
            return diagonal({source: o, target: o});
        })
        .remove();
    // Stash the old positions for transition.
    nodes.forEach(function (d) {
        d.x0 = d.x;
        d.y0 = d.y;
    });
}
var fade = function (opacity) {
    return function (node) {
        svg.selectAll("g.node")
            .filter(function (d) {
                if (node.children) {
                    for (var i in node.children) {
                        if (d.name === node.children[i].name) return false;
                    }
                }
                if (d.name === node.name) return false;
                return -1 === -1;
            })
            .transition()
            .style("opacity", opacity);
        svg.selectAll("path.link")
            .filter(function (d) {
                if (d.source.name === node.name || d.name === node.name) return false;
                return -1 === -1;
            })
            .style("opacity", opacity);
    };
};
var select = function (name) {
    svg.selectAll("g.node")
        .filter(function (d) {
            if (d.name === name) return true;
        })
        .each(function (d) {
            d3.select(this).attr("id", "node-active");
            activeNode = d;
            fade(0.1)(d);
        });
};
var unselect = function () {
    if (activeNode == null) return;
    fade(1)(activeNode);
    d3.select('#node-active').attr("id", null);
    activeNode = null;
};
var paneldetail = function (id, type) {
    $.ajax({
        url: "/saas/tupu_basic/" + id,
        async: false, // 注意此处需要同步
        success: function (data) {
            if (type == "tree") {
                $("#panelinfo2").html(data).show();
            } else {
                $("#panelinfo1").html(data).show();
            }
        }
    });
};
var hidepaneldetail = function (type) {
    if (type == "tree") {
        $("#panelinfo2").hide();
    } else {
        $("#panelinfo1").hide();
    }
};
var opa = function (relation, opa) {
    if ($("#d3treechart").css("display") == "block") {
        var d3svg = svg2;
    } else {
        d3svg = svg;
    }
    d3svg.selectAll("g.node")
        .filter(function (d) {
            if (d.tags != relation) return false;
            return -1 === -1;
        })
        .transition()
        .style("opacity", opa);
};
var filtercnode = function (relation, th) {
    if ($(th).hasClass("nodeopacity")) {
        $(th).removeClass("nodeopacity");
        opa(relation, 1);
    } else {
        $(th).addClass("nodeopacity");
        opa(relation, 0.1);
    }
};
//----------------------------一些函数-----------------------------//
//点击添加子元素
function getNode(id) {       //自定义的一个新的以同步方式从后台取数据的ajax函数
    var mynodes = null;
    $.ajax({
        url: "/saas/tupu_json/" + id + "/?isajax=1",
        async: false, // 注意此处需要同步
        success: function (data) {
            mynodes = data;
        }
    });
    return mynodes;
}
// Toggle children on click.
function click(d, type) {      //重点关注这个函数的不同之处。尤其是else部分
    console.log("click");
    if (d.children) {
        d._children = d.children;
        d.children = null;
    } else if (d._children) {
        d.children = d._children;
        d._children = null;
    } else {
        var mnodes = getNode(d.eid);
        if (mnodes.children != "") {
            d.children = mnodes.children;
        }
    }
    update(d);
}
function click2(d) {      //重点关注这个函数的不同之处。尤其是else部分
    if (d.children) {
        d._children = d.children;
        d.children = null;
    } else if (d._children) {
        d.children = d._children;
        d._children = null;
    } else {
        var mnodes = getNode(d.eid);
        if (mnodes.children != "") {
            d.children = mnodes.children;
        }
    }
    update2(d);
}
//缩放拖拽
function redraw() {
    svg.attr("transform",
        "translate(" + d3.event.translate + ")"
        + " scale(" + d3.event.scale + ")");
}
function redraw2() {
    svg2.attr("transform",
        "translate(" + d3.event.translate + ")"
        + " scale(" + d3.event.scale + ")");
}
function showtext(hideid, showid) {
    $("#" + hideid).hide();
    $("#" + showid).css("display", "inline-block");
    $(".nodetext").css("fill-opacity", 1);
}
function hidetext(hideid, showid) {
    $("#" + hideid).hide();
    $("#" + showid).css("display", "inline-block");
    $(".nodetext").css("fill-opacity", 0);
}
//----------------------------------------------------------------------下钻树图------------------------------------------------------------------------//
var supportsForeignObject = Modernizr.svgforeignobject;
var chartWidth = $("#d3treemap").width();
var chartHeight = $("#d3treemap").height();
var xscale = d3.scale.linear().range([0, chartWidth]);
var yscale = d3.scale.linear().range([0, chartHeight]);
var color = d3.scale.category10();
var headerHeight = 40;
var headerColor = "#555555";
var transitionDuration = 500;
var root3;
var node;
var treemap = d3.layout.treemap()
    .round(false)
    .size([chartWidth, chartHeight])
    .sticky(true)
    .value(function (d) {
        return d.size
    });
var chart = d3.select("#d3treemap")
    .append("svg:svg")
    .attr("width", chartWidth)
    .attr("height", chartHeight)
    .append("svg:g");
var d3tree3 = function (data) {
    node = root3 = data;
    var nodes = treemap.nodes(root3);
    var children = nodes.filter(function (d) {
        return !d.children;
    });
    var parents = nodes.filter(function (d) {
        return d.children;
    });
    // create parent cells
    var parentCells = chart.selectAll("g.cell.parent")
        .data(parents, function (d) {
            return "p-" + d.id;
        });
    var parentEnterTransition = parentCells.enter()
        .append("g")
        .attr("class", "cell parent")
        .on("click", function (d) {
            zoom(d);
        });
    parentEnterTransition.append("rect")
        .attr("width", function (d) {
            return Math.max(0.01, d.dx);
        })
        .attr("height", headerHeight)
        .style("fill", headerColor);
    parentEnterTransition.append('foreignObject')
        .attr("class", "foreignObject")
        .append("xhtml:body")
        .attr("class", "labelbody")
        .append("div")
        .attr("class", "label");
    // update transition
    var parentUpdateTransition = parentCells.transition().duration(transitionDuration);
    parentUpdateTransition.select(".cell")
        .attr("transform", function (d) {
            return "translate(" + d.dx + "," + d.y + ")";
        });
    parentUpdateTransition.select("rect")
        .attr("width", function (d) {
            return Math.max(0.01, d.dx);
        })
        .attr("height", headerHeight)
        .style("fill", headerColor);
    parentUpdateTransition.select(".foreignObject")
        .attr("width", function (d) {
            return Math.max(0.01, d.dx);
        })
        .attr("height", headerHeight)
        .select(".labelbody .label")
        .text(function (d) {
            return d.name;
        });
    // remove transition
    parentCells.exit()
        .remove();
    // create children cells
    var childrenCells = chart.selectAll("g.cell.child")
        .data(children, function (d) {
            return "c-" + d.id;
        });
    // enter transition
    var childEnterTransition = childrenCells.enter()
        .append("g")
        .attr("class", "cell child")
        .on("click", function (d) {
            zoom(node === d.parent ? root3 : d.parent);
        })
        .on("mouseover", function () {
            this.parentNode.appendChild(this); // workaround for bringing elements to the front (ie z-index)
            d3.select(this)
                .select(".background")
                .style("stroke", "#000000");
        })
        .on("mouseout", function () {
            d3.select(this)
                .select(".background")
                .style("stroke", "#FFFFFF");
        });
    childEnterTransition.append("rect")
        .classed("background", true)
        .style("fill", function (d) {
            return d.parent.name;
        });
    childEnterTransition.append('foreignObject')
        .attr("class", "foreignObject")
        .attr("width", function (d) {
            return Math.max(0.01, d.dx);
        })
        .attr("height", function (d) {
            return Math.max(0.01, d.dy);
        })
        .append("xhtml:body")
        .attr("class", "labelbody")
        .append("div")
        .attr("class", "label")
        .text(function (d) {
            return d.name;
        });
    if (supportsForeignObject) {
        childEnterTransition.selectAll(".foreignObject")
        //.style("display", "none");
    } else {
        childEnterTransition.selectAll(".foreignObject .labelbody .label")
        //.style("display", "none");
    }
    // update transition
    var childUpdateTransition = childrenCells.transition().duration(transitionDuration);
    childUpdateTransition.select(".cell")
        .attr("transform", function (d) {
            return "translate(" + d.x + "," + d.y + ")";
        });
    childUpdateTransition.select("rect")
        .attr("width", function (d) {
            return Math.max(0.01, d.dx);
        })
        .attr("height", function (d) {
            return d.dy;
        })
        .style("fill", function (d) {
            return color(d.parent.name);
        });
    childUpdateTransition.select(".foreignObject")
        .attr("width", function (d) {
            return Math.max(0.01, d.dx);
        })
        .attr("height", function (d) {
            return Math.max(0.01, d.dy);
        })
        .select(".labelbody .label")
        .text(function (d) {
            return d.name;
        });
    // exit transition
    childrenCells.exit()
        .remove();
    d3.select("select").on("change", function () {
        treemap.value(this.value == "size" ? size : count)
            .nodes(root3);
        zoom(node);
    });
    zoom(node);
};
function size(d) {
    return d.size;
}
function count(d) {
    return 1;
}
function getRGBComponents(color) {
    var r = color.substring(1, 3);
    var g = color.substring(3, 5);
    var b = color.substring(5, 7);
    return {
        R: parseInt(r, 16),
        G: parseInt(g, 16),
        B: parseInt(b, 16)
    };
}
function idealTextColor(bgColor) {
    var nThreshold = 105;
    var components = getRGBComponents(bgColor);
    var bgDelta = (components.R * 0.299) + (components.G * 0.587) + (components.B * 0.114);
    return ((255 - bgDelta) < nThreshold) ? "#000000" : "#ffffff";
}
function zoom(d) {
    this.treemap
        .padding([headerHeight / (chartHeight / d.dy), 0, 0, 0])
        .nodes(d);
    // moving the next two lines above treemap layout messes up padding of zoom result
    var kx = chartWidth / d.dx;
    var ky = chartHeight / d.dy;
    var level = d;
    xscale.domain([d.x, d.x + d.dx]);
    yscale.domain([d.y, d.y + d.dy]);
    if (node != level) {
        if (supportsForeignObject) {
            chart.selectAll(".cell.child .foreignObject")
            //.style("display", "none");
        } else {
            chart.selectAll(".cell.child .foreignObject .labelbody .label")
            //.style("display", "none");
        }
    }
    var zoomTransition = chart.selectAll("g.cell").transition().duration(transitionDuration)
        .attr("transform", function (d) {
            return "translate(" + xscale(d.x) + "," + yscale(d.y) + ")";
        })
        .each("end", function (d, i) {
            if (!i && (level !== self.root3)) {
                chart.selectAll(".cell.child")
                    .filter(function (d) {
                        return d.parent === self.node; // only get the children for selected group
                    })
                    .select(".foreignObject .labelbody .label")
                    .style("color", function (d) {
                        return idealTextColor(color(d.parent.name));
                    });
                if (supportsForeignObject) {
                    chart.selectAll(".cell.child")
                        .filter(function (d) {
                            return d.parent === self.node; // only get the children for selected group
                        })
                        .select(".foreignObject")
                        .style("display", "");
                } else {
                    chart.selectAll(".cell.child")
                        .filter(function (d) {
                            return d.parent === self.node; // only get the children for selected group
                        })
                        .select(".foreignObject .labelbody .label")
                        .style("display", "");
                }
            }
        });
    zoomTransition.select(".foreignObject")
        .attr("width", function (d) {
            return Math.max(0.01, kx * d.dx);
        })
        .attr("height", function (d) {
            return d.children ? headerHeight : Math.max(0.01, ky * d.dy);
        })
        .select(".labelbody .label")
        .text(function (d) {
            return d.name;
        });
    // update the width/height of the rects
    zoomTransition.select("rect")
        .attr("width", function (d) {
            return Math.max(0.01, kx * d.dx);
        })
        .attr("height", function (d) {
            return d.children ? headerHeight : Math.max(0.01, ky * d.dy);
        })
        .style("fill", function (d) {
            return d.children ? headerColor : color(d.parent.name);
        });
    node = d;
    if (d3.event) {
        d3.event.stopPropagation();
    }
}
